'use strict';  // eslint-disable-line

/**
 * Webpack configuration base class
 */
const fs = require('fs');
const path = require('path');

const npmBase = path.join(__dirname, '../../node_modules');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

const modifySpellLoader = path.resolve(__dirname, '../loaders/modify-spell-loader.js');
const clearI18nLoader = path.resolve(__dirname, '../loaders/clear-i18n-loader.js');

class WebpackBaseConfig {

  constructor() {
    this._config = {};
  }

  /**
   * Get the list of included packages
   * @return {Array} List of included packages
   */
  get includedPackages() {
    return [].map((pkg) => fs.realpathSync(path.join(npmBase, pkg)));
  }

  //noinspection JSAnnotator
  /**
   * Set the config data.
   * This will always return a new config
   * @param {Object} data Keys to assign
   * @return {Object}
   */
  set config(data) {
    this._config = Object.assign({}, this.defaultSettings, data);
    return this._config;
  }

  /**
   * Get the global config
   * @return {Object} config Final webpack config
   */
  get config() {
    return this._config;
  }

  /**
   * Get the environment name
   * @return {String} The current environment
   */
  get env() {
    return 'dev';
  }

  /**
   * Get the absolute path to src directory
   * @return {String}
   */
  get srcPathAbsolute() {
    return path.resolve('./src');
  }

  /**
   * Get the absolute path to tests directory
   * @return {String}
   */
  get testPathAbsolute() {
    return path.resolve('./test');
  }

  get extraCss() {
    return false
  }

  get buildDist() {
    return this.env === 'dist'
  }

  /**
   * Get the default settings
   * @return {Object}
   */
  get defaultSettings() {
    const cssModulesQuery = {
      modules: true,
      importLoaders: 1,
      localIdentName: '[local]'
    };

    return {
      context: this.srcPathAbsolute,
      devtool: 'eval',
      entry: './index.js',
      module: {
        rules: [
          {
            enforce: 'pre',
            test: /\.(js|jsx)?$/,
            include:  [this.srcPathAbsolute],
            loader: 'happypack/loader?id=happyBabel',
          },
          {
            test: /\.(js?|json)$/,
            include: [
              this.srcPathAbsolute
            ],
            use: this.buildDist ? [
              {loader: clearI18nLoader},
              {loader: modifySpellLoader}
            ] : [
              {loader: clearI18nLoader},
            ],
          },
          {
            test: /\.(png|jpg|gif|mp4|ogg|svg|woff|woff2)$/,
            loader: 'file-loader',
            query: {
              limit: 10000,
              name: './images/[hash].[ext]',
              publicPath: '/assets/'
            }
          },
          {
            test: /\.(sass|scss)$/,
            use: this.extraCss ? [MiniCssExtractPlugin.loader, 'happypack/loader?id=happyScss'] : 'happypack/loader?id=happyScss'
          },
          {
            test: /\.less$/,
            use: this.extraCss ? [MiniCssExtractPlugin.loader, 'happypack/loader?id=happyLess'] : 'happypack/loader?id=happyLess'
          },
          {
            test: /\.css$/,
            loaders: [
              { loader: 'style-loader' },
              {
                loader: 'css-loader'
              }
            ]
          },
        ]
      },
      output: {
        path: path.resolve('./dist/assets'),
        filename: this.buildDist ? '[name].[hash].js' : '[name].js',
        publicPath: '/assets/',
        chunkFilename: this.buildDist ? '[name].[chunkhash:5].chunk.js' : '[name].js'
      },
      plugins: [],
      resolve: {
        alias: {
          share: `${this.srcPathAbsolute}/share/`,
          actions: `${this.srcPathAbsolute}/actions/`,
          components: `${this.srcPathAbsolute}/components/`,
          config: `${this.srcPathAbsolute}/config/${this.env}.js`,
          images: `${this.srcPathAbsolute}/images/`,
          stores: `${this.srcPathAbsolute}/stores/`,
          styles: `${this.srcPathAbsolute}/styles/`,
          routes: `${this.srcPathAbsolute}/routes/`,
          service: `${this.srcPathAbsolute}/service/`
        },
        extensions: ['.js', '.jsx'],
        modules: [
          this.srcPathAbsolute,
          'node_modules'
        ]
      }
    };
  }
}

module.exports = WebpackBaseConfig;
